/*
 *  grp.c
 *
 *  Created on: 2010-5-27
 *      Author: liuyond
 */

#include "cpu.h"

extern void ADD_Eb_Ib(cpu_t *cpu, instruction_t *i);
extern void ADD_Ev_Iv(cpu_t *cpu, instruction_t *i);
extern void ADC_Eb_Ib(cpu_t *cpu, instruction_t *i);
extern void ADC_Ev_Iv(cpu_t *cpu, instruction_t *i);
extern void SBB_Eb_Ib(cpu_t *cpu, instruction_t *i);
extern void SBB_Ev_Iv(cpu_t *cpu, instruction_t *i);
extern void SUB_Eb_Ib(cpu_t *cpu, instruction_t *i);
extern void SUB_Ev_Iv(cpu_t *cpu, instruction_t *i);
extern void INC_Eb(cpu_t *cpu, instruction_t *i);
extern void DEC_Eb(cpu_t *cpu, instruction_t *i);
extern void INC_Ev(cpu_t *cpu, instruction_t *i);
extern void DEC_Ev(cpu_t *cpu, instruction_t *i);
extern void CMP_Eb_Ib(cpu_t *cpu, instruction_t *i);
extern void CMP_Ev_Iv(cpu_t *cpu, instruction_t *i);
extern void TEST_Eb_Ib(cpu_t *cpu, instruction_t *i);
extern void TEST_Ev_Iv(cpu_t *cpu, instruction_t *i);
extern void AND_Eb_Ib(cpu_t *cpu, instruction_t *i);
extern void AND_Ev_Iv(cpu_t *cpu, instruction_t *i);
extern void XOR_Eb_Ib(cpu_t *cpu, instruction_t *i);
extern void XOR_Ev_Iv(cpu_t *cpu, instruction_t *i);
extern void OR_Eb_Ib(cpu_t *cpu, instruction_t *i);
extern void OR_Ev_Iv(cpu_t *cpu, instruction_t *i);
extern void NOT_Eb(cpu_t *cpu, instruction_t *i);
extern void NOT_Ev(cpu_t *cpu, instruction_t *i);
extern void NEG_Eb(cpu_t *cpu, instruction_t *i);
extern void NEG_Ev(cpu_t *cpu, instruction_t *i);
extern void MUL_AL_Eb(cpu_t *cpu, instruction_t *i);
extern void MUL_AX_Ev(cpu_t *cpu, instruction_t *i);
extern void DIV_AL_Eb(cpu_t *cpu, instruction_t *i);
extern void DIV_AX_Ev(cpu_t *cpu, instruction_t *i);
extern void IMUL_AL_Eb(cpu_t *cpu, instruction_t *i);
extern void IMUL_AX_Ev(cpu_t *cpu, instruction_t *i);
extern void IDIV_AL_Eb(cpu_t *cpu, instruction_t *i);
extern void IDIV_AX_Ev(cpu_t *cpu, instruction_t *i);
extern void CALL_Jv(cpu_t *cpu, instruction_t *i);
extern void JMP_Jv(cpu_t *cpu, instruction_t *i);
extern void PUSH_Ev(cpu_t *cpu, instruction_t *i);
extern void illegal_opcode(cpu_t *cpu, instruction_t *i);
extern void unimplemented(cpu_t *cpu, instruction_t *i);


void GRP1_Eb_Ib(cpu_t *cpu, instruction_t *i)
{
	switch (i->operand.reg)
	{
		case 0: ADD_Eb_Ib(cpu, i); break;
		case 1:  OR_Eb_Ib(cpu, i); break;
		case 2: ADC_Eb_Ib(cpu, i); break;
		case 3: SBB_Eb_Ib(cpu, i); break;
		case 4: AND_Eb_Ib(cpu, i); break;
		case 5: SUB_Eb_Ib(cpu, i); break;
		case 6: XOR_Eb_Ib(cpu, i); break;
		case 7: CMP_Eb_Ib(cpu, i); break;
	}
}

void GRP1_Ev_Iv(cpu_t *cpu, instruction_t *i)
{
	switch (i->operand.reg)
	{
		case 0: ADD_Ev_Iv(cpu, i); break;
		case 1:  OR_Ev_Iv(cpu, i); break;
		case 2: ADC_Ev_Iv(cpu, i); break;
		case 3: SBB_Ev_Iv(cpu, i); break;
		case 4: AND_Ev_Iv(cpu, i); break;
		case 5: SUB_Ev_Iv(cpu, i); break;
		case 6: XOR_Ev_Iv(cpu, i); break;
		case 7: CMP_Ev_Iv(cpu, i); break;
	}
}

void GRP2_Eb(cpu_t *cpu, instruction_t *i)
{
	unimplemented(cpu, i);
}
void GRP2_Ev(cpu_t *cpu, instruction_t *i)
{
	unimplemented(cpu, i);
}
void GRP2_Eb_CL(cpu_t *cpu, instruction_t *i)
{
	unimplemented(cpu, i);
}
void GRP2_Ev_CL(cpu_t *cpu, instruction_t *i)
{
	unimplemented(cpu, i);
}

void GRP3_Eb(cpu_t *cpu, instruction_t *i)
{
	switch (i->operand.reg)
	{
		case 0: TEST_Eb_Ib(cpu, i); break;
		case 1: TEST_Eb_Ib(cpu, i); break;
		case 2:  NOT_Eb(cpu, i);    break;
		case 3:  NEG_Eb(cpu, i);    break;
		case 4:  MUL_AL_Eb(cpu, i); break;
		case 5: IMUL_AL_Eb(cpu, i); break;
		case 6:  DIV_AL_Eb(cpu, i); break;
		case 7: IDIV_AL_Eb(cpu, i); break;
	}
}

void GRP3_Ev(cpu_t *cpu, instruction_t *i)
{
	switch (i->operand.reg)
	{
		case 0: TEST_Ev_Iv(cpu, i); break;
		case 1: TEST_Ev_Iv(cpu, i); break;
		case 2:  NOT_Ev(cpu, i);    break;
		case 3:  NEG_Ev(cpu, i);    break;
		case 4:  MUL_AX_Ev(cpu, i); break;
		case 5: IMUL_AX_Ev(cpu, i); break;
		case 6:  DIV_AX_Ev(cpu, i); break;
		case 7: IDIV_AX_Ev(cpu, i); break;
	}
}

void GRP4_Eb(cpu_t *cpu, instruction_t *i)
{
	switch (i->operand.reg)
	{
		case 0: INC_Eb(cpu, i); break;
		case 1: DEC_Eb(cpu, i); break;
		case 2: illegal_opcode(cpu, i); break;
		case 3: illegal_opcode(cpu, i); break;
		case 4: illegal_opcode(cpu, i); break;
		case 5: illegal_opcode(cpu, i); break;
		case 6: illegal_opcode(cpu, i); break;
		case 7: illegal_opcode(cpu, i); break;
	}
}

void GRP5_Ev(cpu_t *cpu, instruction_t *i)
{
	switch (i->operand.reg)
	{
		case 0: INC_Ev(cpu, i); break;
		case 1: DEC_Ev(cpu, i); break;
		case 2: CALL_Jv(cpu, i); break;
		case 3: CALL_Jv(cpu, i); break;
		case 4: JMP_Jv(cpu, i); break;
		case 5: JMP_Jv(cpu, i); break;
		case 6: PUSH_Ev(cpu, i); break;
		case 7: illegal_opcode(cpu, i); break;
	}
}
